package com.moka.db.dao;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import com.moka.db.DatabaseEntity;
import com.moka.db.Table;

public class BaseDao {

	SQLiteOpenHelper helper;
	
	private static ExecutorService pool = Executors.newFixedThreadPool(20);
	
	public static abstract class DatabaseAccessCallback<T>{
		
		public void execute(List<T> list){}
		
		public void execute(T t){}
		
		public void execute(){}
		
	}

	public BaseDao(SQLiteOpenHelper helper) {
		
		this.helper = helper;
	
	}

	public void deleteAll(final Class<? extends DatabaseEntity> clazz){
		
		deleteAll(clazz,null);
		
	}
	
	public void deleteAll(final Class<? extends DatabaseEntity> clazz,final DatabaseAccessCallback<?> callback){
		
		Thread thread = new Thread(){
			
			@Override
			public void run() {

				SQLiteDatabase db =  helper.getWritableDatabase();
				
				try{
					
					Table table = clazz.getAnnotation(Table.class);
					
					StringBuffer sql = new StringBuffer();

					String tableName = table.name();
					
					sql.append("delete from ").append(tableName);
					
					db.execSQL(sql.toString());
					
				
				} catch (Exception e) {
					
					e.printStackTrace();
					
				}finally{
					
					if(callback!=null){
						
						callback.execute();
						
					}
					
				}
				
			}
			
		};
		
		pool.execute(thread);
		
	}
	
	public void delete(final DatabaseEntity entity){
		
		if(entity !=null){
		
			delete(entity,null);
		
		}
		
	}
	
	public void delete(final DatabaseEntity entity,final DatabaseAccessCallback<?> callback) {
		
		Thread thread = new Thread(){
			
			@Override
			public void run() {

				SQLiteDatabase db =  helper.getWritableDatabase();
				
				try{
					
					entity.delete(db);
				
				} catch (Exception e) {
					
					e.printStackTrace();
					
				}finally{
					
					if(callback!=null){
						
						callback.execute();
						
					}
					
				}
				
			}
			
		};
		
		pool.execute(thread);
	}
	
	public void save(final DatabaseEntity entity){
		
		save(entity,null);
		
	}

	public void save(final DatabaseEntity entity,final DatabaseAccessCallback<?> callback) {
		
		Thread thread = new Thread(){
			
			@Override
			public void run() {

				SQLiteDatabase db =  helper.getWritableDatabase();
				
				try{
					
					entity.save(db);
					
				} catch (Exception e) {
					
					e.printStackTrace();
					
				}finally{
					
					if(callback!=null){
						
						callback.execute();
						
					}
				}
			
			}
			
		};
		
		pool.execute(thread);
		
	}

	
	public void update(final DatabaseEntity entity) {
		
		update(entity,null);
	}
	
	public void update(final DatabaseEntity entity,final DatabaseAccessCallback<?> callback) {
		
		Thread thread = new Thread(){
			
			@Override
			public void run() {

				SQLiteDatabase db =  helper.getWritableDatabase();
				
				try{
					
					entity.update(db);
					
				} catch (Exception e) {
					
					e.printStackTrace();
					
				}finally{
					
					if(callback!=null){
						
						callback.execute();
						
					}
					
				}
			
			}
			
		};
		
		pool.execute(thread);
		
	}

	public <T> IQuery<T> createQuery(Class<T> clazz) {
		
		IQuery<T> query = new Query<T>(helper,clazz);
		
		return query;
	}
	
	
}
